/* 
    动机：
        1. 当一段代码同时处理两件不同的事时，就可以把它拆分成各自独立的模块；
        2. 这样当需要修改时，就可以单独处理每个主题。

    做法：
        1. 将第二阶段的代码提炼成独立的函数；
        2. 测试；
        3. 引入一个中转数据结构，将其作为参数传递到提炼出的新函数的参数列表；
        4. 测试；
        5. 注意检查提炼出的“第二阶段函数”的每个参数，如果某个参数丠第一阶段用到，就将其移入中转数据结构。每次搬移之后都要测试；
        6. 对第一阶段的代码运用【提炼函数】，让提炼出的函数返回中转数据结构。
*/

function priceOrder(product, quantity, shippingMethod) {
    const basePrice = product.basePrice * quantity;
    const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate;
    const shippingPerCase = (basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountFee : shippingMethod.feePerCase;
    const shippingCost = quantity * shippingPerCase;
    const price = basePrice - discount + shippingCost;

    return price;
}

/******************************************************* */

function priceOrder(product, quantity, shippingMethod) {
    const basePrice = product.basePrice * quantity;
    const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate;

    const priceData = {};
    priceData.basePrice = basePrice;
    priceData.quantity = quantity;
    priceData.discount = discount;

    const price = applyShipping(priceData, shippingMethod);
    return price;
}

/* 
    1. 增加中转数据结构 priceData
    2. 观察 applyShipping() 中原参数  basePrice, shippingMethod, quantity, discount
    3. 依次搬移  basePrice, shippingMethod, quantity, discount 参数 到中转数据结构中
    4. 因为 第一阶段没有用到 shippingMethod，所以它可以保留
*/
function applyShipping(priceData, shippingMethod) {
    const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? priceData.shippingMethod.discountFee : priceData.shippingMethod.feePerCase;
    const shippingCost = priceData.quantity * shippingPerCase;
    const price = priceData.basePrice - priceData.discount + shippingCost;

    return price;
}
/******************************************************* */
function priceOrder(product, quantity, shippingMethod) {
    const priceData = calculatePricingData(product, quantity);
    return applyShipping(priceData, shippingMethod);
}

function calculatePricingData(product, quantity) {
    const basePrice = product.basePrice * quantity;
    const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate;
    return { basePrice: basePrice, quantity: quantity, discount: discount };
}

function applyShipping(priceData, shippingMethod) {
    const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? priceData.shippingMethod.discountFee : priceData.shippingMethod.feePerCase;
    const shippingCost = priceData.quantity * shippingPerCase;
    return priceData.basePrice - priceData.discount + shippingCost;
}
